package conf

import (
	"fmt"
	"gitee.com/whilew/cream/pkg/util/xcast"
	"strings"
)

func Print() {
	configuration.Print()
}
func (c *Configuration) Print() {
	c.settings.Print("")
}
func (ss *Settings) Print(key string) {
	for i, t := range *ss {
		if len(t.Childs) > 0 {
			(*ss)[i].Childs.Print(key + t.Key + ".")
		}
		if t.Value != nil {
			fmt.Println(key+t.Key, "=", t.Value)
		}
	}
}

func (c *Configuration) find(key string) interface{} {
	for _, t := range c.dataSource {
		if v := t.Get(key); v != nil {
			return v
		}
	}
	key = strings.ToLower(key)
	keys := strings.Split(key, ".")
	v := c.settings.find(keys)
	if v == nil {
		if vv := find_conf_in_flag_and_env(key); vv != "" {
			return vv
		}
	}
	return v
}
func (c *Configuration) Get(key string) interface{} {
	return c.find(key)
}
func (c *Configuration) GetString(key string) string {
	return xcast.ToString(c.Get(key))
}
func (c *Configuration) GetStringd(key, dv string) string {
	v := c.GetString(key)
	if v == "" {
		return dv
	}
	return v
}
func (c *Configuration) GetBool(key string) bool {
	return xcast.ToBool(c.Get(key))
}
func (c *Configuration) GetBoold(key string, dv bool) bool {
	if v := c.Get(key); v == nil {
		return dv
	} else {
		return xcast.ToBool(v)
	}
}
func (c *Configuration) GetInt(key string) int {
	return xcast.ToInt(c.Get(key))
}
func (c *Configuration) GetIntd(key string, dv int) int {
	if v := c.Get(key); v == nil {
		return dv
	} else {
		return xcast.ToInt(v)
	}
}
func (c *Configuration) GetInt64(key string) int64 {
	return xcast.ToInt64(c.Get(key))
}
func (c *Configuration) GetInt64d(key string, dv int64) int64 {
	if v := c.Get(key); v == nil {
		return dv
	} else {
		return xcast.ToInt64(v)
	}
}
func (c *Configuration) GetFloat64(key string) float64 {
	return xcast.ToFloat64(c.Get(key))
}
func (c *Configuration) GetFloat64d(key string, dv float64) float64 {
	if v := c.Get(key); v == nil {
		return dv
	} else {
		return xcast.ToFloat64(v)
	}
}
func (c *Configuration) GetStringSlice(key string) []string {
	return xcast.ToStringSlice(c.Get(key))
}
func (c *Configuration) GetChildd(key string) *Settings {
	if v := c.Get(key); v == nil {
		return &Settings{}
	} else {
		if v, ok := v.(*Settings); ok {
			return v
		} else {
			return &Settings{}
		}
	}
}

// 从env和flag中寻找配置
func find_conf_in_flag_and_env(key string) string {
	v := get_flag_config(key)
	if v == "" {
		return get_env_config(key)
	}
	return v
}
